﻿using IOP.Models.Message;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace IOP.AspNetCore.Extension.Auth
{
    /// <summary>
    /// JWT认证扩展
    /// </summary>
    public static class JWTExtensions
    {
        /// <summary>
        /// 创建令牌
        /// </summary>
        /// <param name="option"></param>
        /// <param name="roles"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static JwtMessage CreateToken(this TokenOptions option, IEnumerable<string> roles, string userName)
        {
            var now = DateTime.UtcNow;

            List<Claim> claims = new List<Claim>();
            claims.Add(new Claim(JwtRegisteredClaimNames.Sub, userName));
            claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()));
            claims.Add(new Claim(JwtRegisteredClaimNames.Iat, now.ToUniversalTime().ToString(),
                ClaimValueTypes.Integer64));
            claims.Add(new Claim(ClaimTypes.Name, userName));
            foreach (var item in roles)
            {
                claims.Add(new Claim(ClaimTypes.Role, item));
            }

            var jwt = new JwtSecurityToken(
                issuer: option.Issuer,
                audience: option.Audience,
                claims: claims,
                notBefore: now,
                expires: now.Add(option.Expiration),
                signingCredentials: option.SigningCredentials);
            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
            return new JwtMessage
            {
                AccessToken = encodedJwt,
                ExpiresIn = (long)option.Expiration.TotalSeconds,
                TokenType = "Bearer"
            };
        }
    }
}
